﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

using CommunicatorAPI;
using CommunicatorPrivate;

using OCSDKWrapper;
using OCSDKWrapper.MOCEventArgs;

namespace OCSDKWrapper.SampleApp
{
    public partial class MOCSampleApp : Window
    {
        private MOCAutomation _MOCAutomation;
        private MOCEventLogCollection _events;
        
        internal delegate void GenericDelegate();

        public MOCSampleApp()
        {
            InitializeComponent();

            this.Loaded += new RoutedEventHandler(MOCSampleApp_Loaded);
            this.Unloaded += new RoutedEventHandler(MOCSampleApp_Unloaded);
        }

        void MOCSampleApp_Loaded(object sender, RoutedEventArgs e)
        {
            // Wire up the MOCAutomation ConnectionStateChanged event
            //
            MOCAutomation.ConnectionStateChanged += 
                new EventHandler<ConnectionStateChangedEventArgs>(ConnectionStateChanged);

            // Singleton instance of MOCAutomation class
            //
            _MOCAutomation = MOCAutomation.Instance;

            // Create collection of Communicator events to display
            //
            _events = new MOCEventLogCollection();
            this.communicatorEvents.ItemsSource = _events;

            // Wire up all other Communicator events
            //  This might not be necessary for your typical application.
            //  We're doing it here just to monitor which events get raised by Communicator.
            //
            _MOCAutomation.AppShutdown += new EventHandler<EventArgs>(AppShutdown);
            _MOCAutomation.ContactAddedToGroup += new EventHandler<ContactAddedToGroupEventArgs>(ContactAddedToGroup);
            _MOCAutomation.ContactBlockChange += new EventHandler<ContactBlockChangeEventArgs>(ContactBlockChange);
            _MOCAutomation.ContactFriendlyNameChange += new EventHandler<ContactFriendlyNameChangeEventArgs>(ContactFriendlyNameChange);
            _MOCAutomation.ContactListAdd += new EventHandler<ContactListAddEventArgs>(ContactListAdd);
            _MOCAutomation.ContactListRemove += new EventHandler<ContactListRemoveEventArgs>(ContactListRemove);
            _MOCAutomation.ContactPagerChange += new EventHandler<ContactPagerChangeEventArgs>(ContactPagerChange);
            _MOCAutomation.ContactPhoneChange += new EventHandler<ContactPhoneChangeEventArgs>(ContactPhoneChange);
            _MOCAutomation.ContactPropertyChange += new EventHandler<ContactPropertyChangeEventArgs>(ContactPropertyChange);
            _MOCAutomation.ContactRemovedFromGroup += new EventHandler<ContactRemovedFromGroupEventArgs>(ContactRemovedFromGroup);
            _MOCAutomation.ContactResolved += new EventHandler<ContactResolvedEventArgs>(ContactResolved);
            _MOCAutomation.ContactStatusChange += new EventHandler<ContactStatusChangeEventArgs>(ContactStatusChange);
            _MOCAutomation.GroupAdded += new EventHandler<GroupAddedEventArgs>(GroupAdded);
            _MOCAutomation.GroupNameChanged += new EventHandler<GroupNameChangedEventArgs>(GroupNameChanged);
            _MOCAutomation.GroupRemoved += new EventHandler<GroupRemovedEventArgs>(GroupRemoved);
            _MOCAutomation.IMWindowContactAdded += new EventHandler<IMWindowContactAddedEventArgs>(IMWindowContactAdded);
            _MOCAutomation.IMWindowContactRemoved += new EventHandler<IMWindowContactRemovedEventArgs>(IMWindowContactRemoved);
            _MOCAutomation.IMWindowCreated += new EventHandler<IMWindowCreatedEventArgs>(IMWindowCreated);
            _MOCAutomation.IMWindowDestroyed += new EventHandler<IMWindowDestroyedEventArgs>(IMWindowDestroyed);
            _MOCAutomation.MyFriendlyNameChange += new EventHandler<MyFriendlyNameChangeEventArgs>(MyFriendlyNameChange);
            _MOCAutomation.MyPhoneChange += new EventHandler<MyPhoneChangeEventArgs>(MyPhoneChange);
            _MOCAutomation.MyPropertyChange += new EventHandler<MyPropertyChangeEventArgs>(MyPropertyChange);
            _MOCAutomation.MyStatusChange += new EventHandler<MyStatusChangeEventArgs>(MyStatusChange);
            _MOCAutomation.Signin += new EventHandler<SigninEventArgs>(Signin);
            _MOCAutomation.Signout += new EventHandler<EventArgs>(Signout);
            _MOCAutomation.UnreadEmailChange += new EventHandler<UnreadEmailChangeEventArgs>(UnreadEmailChange);
        }

        void MOCSampleApp_Unloaded(object sender, RoutedEventArgs e)
        {
            this.Loaded -= new RoutedEventHandler(MOCSampleApp_Loaded);
        }

        #region Events Exposed by Office Communicator SDK

        void UnreadEmailChange(object sender, UnreadEmailChangeEventArgs e)
        {
            AddEvent("UnreadEmailChange");
        }

        void Signout(object sender, EventArgs e)
        {
            AddEvent("Signout");
        }

        void Signin(object sender, SigninEventArgs e)
        {
            AddEvent("Signin");
        }

        void MyStatusChange(object sender, MyStatusChangeEventArgs e)
        {
            this.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal,
                new GenericDelegate(
                    delegate
                    {
                        myStatus.Text = MOCAutomation.Instance.GetTextStatus(e.mMyStatus);
                    }));

            AddEvent("MyStatusChange");
        }

        void MyPropertyChange(object sender, MyPropertyChangeEventArgs e)
        {
            AddEvent("MyPropertyChange");
        }

        void MyPhoneChange(object sender, MyPhoneChangeEventArgs e)
        {
            AddEvent("MyPhoneChange");
        }

        void MyFriendlyNameChange(object sender, MyFriendlyNameChangeEventArgs e)
        {
            AddEvent("MyFriendlyNameChange");
        }

        void IMWindowDestroyed(object sender, IMWindowDestroyedEventArgs e)
        {
            AddEvent("IMWindowDestroyed");
        }

        void IMWindowCreated(object sender, IMWindowCreatedEventArgs e)
        {
            AddEvent("IMWindowCreated");
        }

        void IMWindowContactRemoved(object sender, IMWindowContactRemovedEventArgs e)
        {
            AddEvent("IMWindowContactRemoved");
        }

        void IMWindowContactAdded(object sender, IMWindowContactAddedEventArgs e)
        {
            AddEvent("IMWindowContactAdded");
        }

        void GroupRemoved(object sender, GroupRemovedEventArgs e)
        {
            AddEvent("GroupRemoved");
        }

        void GroupNameChanged(object sender, GroupNameChangedEventArgs e)
        {
            AddEvent("GroupNameChanged");
        }

        void GroupAdded(object sender, GroupAddedEventArgs e)
        {
            AddEvent("GroupAdded");
        }

        void ContactStatusChange(object sender, ContactStatusChangeEventArgs e)
        {
            AddEvent("ContactStatusChange");
        }

        void ContactResolved(object sender, ContactResolvedEventArgs e)
        {
            AddEvent("ContactResolved");
        }

        void ContactRemovedFromGroup(object sender, ContactRemovedFromGroupEventArgs e)
        {
            AddEvent("ContactRemovedFromGroup");
        }

        void ContactPropertyChange(object sender, ContactPropertyChangeEventArgs e)
        {
            AddEvent("ContactPropertyChange");
        }

        void ContactPhoneChange(object sender, ContactPhoneChangeEventArgs e)
        {
            AddEvent("ContactPhoneChange");
        }

        void ContactPagerChange(object sender, ContactPagerChangeEventArgs e)
        {
            AddEvent("ContactPagerChange");
        }

        void ContactListRemove(object sender, ContactListRemoveEventArgs e)
        {
            AddEvent("ContactListRemove");
        }

        void ContactListAdd(object sender, ContactListAddEventArgs e)
        {
            AddEvent("ContactListAdd");
        }

        void ContactFriendlyNameChange(object sender, ContactFriendlyNameChangeEventArgs e)
        {
            AddEvent("ContactFriendlyNameChange");
        }

        void ContactBlockChange(object sender, ContactBlockChangeEventArgs e)
        {
            AddEvent("ContactBlockChange");
        }

        void ContactAddedToGroup(object sender, ContactAddedToGroupEventArgs e)
        {
            AddEvent("ContactAddedToGroup");
        }

        void AppShutdown(object sender, EventArgs e)
        {
            AddEvent("AppShutdown");
        }

        #endregion

        void ConnectionStateChanged(object sender, ConnectionStateChangedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal,
                new GenericDelegate(
                    delegate
                    {
                        connectionStatus.Text =
                            e.Connected == true ? "Connected" : "Not connected";

                        myStatus.Text = MOCAutomation.Instance.GetTextStatus(MOCAutomation.Instance.GetSignedInUser());
                    }));
        }

        void AddEvent(string eventName)
        {

            this.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal,
                new GenericDelegate(
                    delegate
                    {
                        this._events.Add(
                            new MOCEventLog()
                            {
                                EventName = eventName,
                                EventOccurred = DateTime.Now
                            });

                        this.communicatorEvents.ItemsSource = _events;
                    }));
        }
    }

    class MOCEventLog
    {
        public string EventName { get; set; }
        public DateTime EventOccurred { get; set; }
    }

    class MOCEventLogCollection : ObservableCollection<MOCEventLog> {}
} 